<script setup lang="tsx">
import {
  reactive,
  ref,
  unref,
  markRaw,
  shallowRef,
  provide,
  shallowReactive,
  type Component
} from 'vue'
import { ContentWrap } from '@/components/ContentWrap'
import { Table } from '@/components/Table'
import Add from './component/Add.vue'
import Modify from './component/Modify.vue'
import { ElCollapseTransition, ElSwitch, ElMessage } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { BaseButton } from '@/components/Button'
import { getListApi, delUserApi, updateStatusApi, type Row } from '@/api/system/menu'

defineOptions({
  name: 'Menu'
})
const comId = reactive({
  Add: markRaw(Add),
  Modify: markRaw(Modify)
})
const crudSchemas = reactive<CrudSchema[]>([
  {
    field: 'selection',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: { type: 'selection' }
  },
  {
    field: 'name',
    label: '菜单名称',
    search: { hidden: true },
    form: { hidden: true },
    table: {
      align: 'left',
      headerAlign: 'left'
    }
  },
  {
    field: 'order_num',
    label: '排序',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'path',
    label: '请求地址',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'status',
    label: '状态',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: {
      width: '200px',
      slots: {
        default: ({ row }) => {
          return (
            <ElSwitch
              v-model={row.status}
              active-value={1}
              inactive-value={2}
              loading={switchLoading.value}
              beforeChange={() => changeStatus(row)}
            />
          )
        }
      }
    }
  },
  {
    field: 'menu_type_text',
    label: '菜单类型',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'perms',
    label: '权限标识',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'action',
    width: '260px',
    label: '操作',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: {
      slots: {
        default: ({ row }) => {
          return (
            <>
              <BaseButton type="primary" onClick={() => modifyAction(row)}>
                编辑
              </BaseButton>
            </>
          )
        }
      }
    }
  }
])

// @ts-ignore
const { allSchemas } = useCrudSchemas(crudSchemas)

const ids = ref<string[]>([])

const searchParams = ref()
const tableData = ref([] as any)
const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState
    const res = await getListApi({
      page: unref(currentPage),
      limit: unref(pageSize),
      ...unref(searchParams)
    })
    tableData.value = res.data.list
    return {
      list: res.data.list,
      total: res.data.count
    }
  },
  fetchDelApi: async () => {
    const res = await delUserApi({ id: unref(ids).join(',') })
    return !!res
  }
})
const { loading, dataList } = tableState
const { getList, getElTableExpose, delList } = tableMethods

const showCollapse = ref(false)
let currentAction = shallowRef()
let currentRow = shallowReactive<any>({})
const action = (component: Component) => {
  currentAction.value = component
  if (showCollapse.value === false) showCollapse.value = true
}
const closeCollapse = () => {
  showCollapse.value = false
}
const delLoading = ref(false)
// 新增
const addAction = () => {
  Object.assign(currentRow, {
    id: '',
    name: '',
    parent_id: 0,
    order_num: '',
    path: '',
    menu_type: 'M',
    perms: '',
    component: '',
    query: '',
    icon: '',
    visible: ''
  })
  action(comId['Add'])
}
// 编辑
const modifyAction = async (row: Row) => {
  const currentRowData = {
    id: row.id,
    name: row.name,
    parent_id: row.parent_id,
    order_num: row.order_num,
    path: row.path,
    menu_type: row.menu_type,
    perms: row.perms,
    component: row.component,
    query: row.query,
    icon: row.icon,
    visible: row.visible
  }
  Object.assign(currentRow, currentRowData)
  action(comId['Modify'])
}
const delData = async (row: Row | null) => {
  const elTableExpose = await getElTableExpose()
  ids.value = row ? [row.id] : elTableExpose?.getSelectionRows().map((v: Row) => v.id) || []
  delLoading.value = true
  await delList(unref(ids).length).finally(() => {
    delLoading.value = false
  })
}
const switchLoading = ref(false)
const changeStatus = async (row) => {
  const val = {
    '1': 2,
    '2': 1
  }
  switchLoading.value = true
  try {
    const res = await updateStatusApi({ status: val[row.status], id: row.id })
    if (res) ElMessage.success(res.msg)
    return !!res
  } finally {
    switchLoading.value = false
  }
}
provide('currentRow', currentRow)
</script>

<template>
  <ContentWrap title="菜单管理">
    <div class="mb-10px">
      <BaseButton type="primary" @click="addAction">新增</BaseButton>
      <BaseButton :loading="delLoading" type="danger" @click="delData(null)">删除</BaseButton>
    </div>

    <el-collapse-transition>
      <component
        :is="currentAction"
        @close="closeCollapse"
        @get-list="getList"
        v-if="showCollapse"
      />
    </el-collapse-transition>

    <Table
      :columns="allSchemas.tableColumns"
      :data="dataList"
      :loading="loading"
      @register="tableRegister"
    />
  </ContentWrap>
</template>
